package contrl

import (
	"core/env"
	"core/minio_client"
	"core/mysql"
	"core/rds"
	"core/utils"
	"db"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/go-xorm/builder"
)

type PictureOnlineContrl struct{}

type PicOnlineItem struct {
	db.PicOnline
	MiniUrl string
}

type PictureOnlineList struct {
	Count int64
	List  []PicOnlineItem
}

// 上线和未上线图片列表
func (*PictureOnlineContrl) ListOnline(c *gin.Context) (res interface{}, e Error) {
	online := GetBool(c, "online")
	page := utils.Max(GetInt(c, "page"), 1)
	rows := utils.Min(GetInt(c, "rows"), 30)

	pictures := make([]db.PicOnline, 0)
	cond := builder.NewCond().And(builder.Eq{"online": online})
	count, err := mysql.FindList(&pictures, &mysql.Cond{
		Start: (page - 1) * rows,
		Limit: rows,
		Asc:   "id",
		Cond:  cond,
	})
	if err != nil {
		return nil, GenError(err)
	}

	list := make([]PicOnlineItem, len(pictures))
	for k, picture := range pictures {
		list[k] = PicOnlineItem{
			PicOnline: picture,
			MiniUrl:   genPictureURL(env.GetMinPicName(picture.Name)),
		}
	}

	res = PictureOnlineList{
		Count: count,
		List:  list,
	}
	return
}

// 新增待上线图片（批量）
func (*PictureOnlineContrl) AddPicture(c *gin.Context) (res interface{}, e Error) {
	idsStr := GetString(c, "ids")

	ids := strings.Split(idsStr, "_")
	if len(ids) == 0 {
		return nil, GenErrorMsg("ids 参数错误")
	}
	var err error
	for _, idStr := range ids {
		id := utils.ToInt64(idStr)
		lovePicture := &db.PicLoveMysql{ID: id}
		err = mysql.Load(lovePicture)
		if err != nil {
			return nil, GenError(err)
		}
		onlinePicture := &db.PicOnline{
			OriginName:        lovePicture.OriginName,
			Name:              lovePicture.Name,
			Comment:           lovePicture.Comment,
			AuthorName:        lovePicture.AuthorName,
			AuthorUID:         lovePicture.AuthorUID,
			UploadId:          lovePicture.UploadId,
			UploadAtUnix:      lovePicture.UploadAtUnix,
			Online:            false,
			JigsawName:        lovePicture.OriginName,
			DragonBonesName:   "",
			JigsawSizeId:      2,
			JigsawListId:      0,
			ListIndexId:       0,
			IsRotate:          true,
			IsShow:            true,
			FixedNum:          7,
			StartNum:          0,
			GoldNum:           2,
			MiniIntro:         "拼图正式开启",
			Water:             2,
			MusicName:         "",
			ShareImgName:      "default_1",
			AnimateFullScreen: "FullScreen",
			CreateTime:        time.Now().Unix(),
			Animate:           "",
		}
		err = mysql.Create(onlinePicture)
		if err != nil {
			return nil, GenError(err)
		}
		err = mysql.Del(&db.PicLoveMysql{ID: id})
		if err != nil {
			return nil, GenError(err)
		}
	}
	res = "ok"
	return
}

// 更新图片内容（包含待上线和已上线）
func (*PictureOnlineContrl) UpdatePicture(c *gin.Context) (res interface{}, e Error) {
	id := GetInt64(c, "id")
	if id <= 0 {
		return nil, GenErrorMsg("id 参数错误")
	}
	picture := &db.PicOnline{ID: id}
	err := mysql.Load(picture)
	if err != nil {
		return nil, GenError(err)
	}
	cols := make(Fields, 0)
	online := picture.Online

	// 更新字段
	ParseString(c, db.PicFieldOriginName, &picture.OriginName, &cols)
	ParseString(c, db.PicFieldName, &picture.Name, &cols)
	ParseString(c, db.PicFieldComment, &picture.Comment, &cols)
	ParseString(c, db.PicFieldAuthorName, &picture.AuthorName, &cols)
	ParseInt64(c, db.PicFieldAuthorUID, &picture.AuthorUID, &cols)
	ParseBool(c, db.PicFieldOnline, &picture.Online, &cols)
	ParseString(c, db.PicFieldJigsawName, &picture.JigsawName, &cols)
	ParseString(c, db.PicFieldDragonBonesName, &picture.DragonBonesName, &cols)
	ParseInt(c, db.PicFieldJigsawSizeId, &picture.JigsawSizeId, &cols)
	ParseInt(c, db.PicFieldJigsawListId, &picture.JigsawListId, &cols)
	ParseInt(c, db.PicFieldListIndexId, &picture.ListIndexId, &cols)
	ParseBool(c, db.PicFieldIsRotate, &picture.IsRotate, &cols)
	ParseBool(c, db.PicFieldIsShow, &picture.IsShow, &cols)
	ParseInt(c, db.PicFieldFixedNum, &picture.FixedNum, &cols)
	ParseInt(c, db.PicFieldStartNum, &picture.StartNum, &cols)
	ParseInt(c, db.PicFieldGoldNum, &picture.GoldNum, &cols)
	ParseString(c, db.PicFieldMiniIntro, &picture.MiniIntro, &cols)
	ParseInt(c, db.PicFieldWater, &picture.Water, &cols)
	ParseString(c, db.PicFieldMusicName, &picture.MusicName, &cols)
	ParseString(c, db.PicFieldShareImgName, &picture.ShareImgName, &cols)
	ParseString(c, db.PicFieldAnimateFullScreen, &picture.AnimateFullScreen, &cols)
	ParseInt64(c, db.PicFieldCreateTime, &picture.CreateTime, &cols)
	ParseString(c, db.PicFieldAnimateFullScreen, &picture.AnimateFullScreen, &cols)
	ParseString(c, db.PicFieldAnimate, &picture.Animate, &cols)

	if len(cols) == 0 {
		return nil, GenErrorMsg("请输入要改变的参数")
	}

	if picture.CreateTime == 0 {
		picture.CreateTime = time.Now().Unix()
		cols = append(cols, db.PicFieldCreateTime)
	}
	// 更新mysql
	err = mysql.UpdateCol(id, picture, cols...)
	if err == mysql.NotFound {
		return nil, GenErrorMsg("您啥都没改")
	}
	if err != nil {
		return nil, GenError(err)
	}

	// 更新redis
	err = picture.Save(db.PicFieldsConfig...)
	if err != nil {
		utils.Error(err)
		return nil, GenError(err)
	}
	if online && !picture.Online {
		err = db.SavePlayerPicStatus(false, picture)
		if err != nil {
			return nil, GenError(err)
		}
	}

	res = "ok"
	return
}

// 上线图片(批量或单个)
func (*PictureOnlineContrl) OnlineMulti(c *gin.Context) (res interface{}, e Error) {
	idsStr := GetString(c, "ids")

	ids := strings.Split(idsStr, "_")
	if len(ids) == 0 {
		return nil, GenErrorMsg("ids 参数错误")
	}
	var err error
	for _, idStr := range ids {
		id := utils.ToInt64(idStr)

		// 更新mysql
		pic := &db.PicOnline{ID: id}
		err = mysql.Load(pic)
		pic.Online = true
		err = mysql.UpdateCol(id, pic, db.PicFieldOnline)
		if err != nil {
			return nil, GenError(err)
		}

		// 同步到redis
		err = pic.Save(db.PicFieldsAll...)
		if err != nil {
			utils.Error(err)
			return nil, GenError(err)
		}
		picRedis := rds.GetPicClient()
		err = picRedis.UpdateRankWithScore(db.MakePicRankKeyNew(), strconv.FormatInt(id, 10), float64(time.Now().Unix()), db.PicRankNewLimit)
		err = picRedis.UpdateRankWithScore(db.MakePicRankKeyLove(), strconv.FormatInt(id, 10), 0, db.PicRankNewLimit)
		if err != nil {
			utils.Error(err)
			return nil, GenError(err)
		}

		// 保存用户上传信息
		utils.Info("保存用户上传信息")
		err = db.SavePlayerPicStatus(true, pic)
		if err != nil {
			utils.Error(err)
			return nil, GenError(err)
		}
	}

	res = "ok"
	return
}

// 批量删除
func (*PictureOnlineContrl) DelMultiPicture(c *gin.Context) (res interface{}, e Error) {
	online := GetBool(c, "online")
	idsStr := GetString(c, "ids")

	ids := strings.Split(idsStr, "_")
	if len(ids) == 0 {
		return nil, GenErrorMsg("ids 参数错误")
	}
	var err error
	for _, idStr := range ids {
		if idStr == "" {
			continue
		}
		id := utils.ToInt64(idStr)
		picture := &db.PicOnline{ID: id, Online: online}
		err = mysql.Load(picture)
		if err != nil {
			return nil, GenError(err)
		}

		// 删除redis
		picClient := rds.GetPicClient()
		err = picClient.Del(db.MakePicKey(id)).Err()
		if err != nil {
			utils.Error(err)
		}
		err = picClient.ZRem(db.MakePicRankKeyNew(), strconv.FormatInt(id, 10)).Err()
		err = picClient.ZRem(db.MakePicRankKeyLove(), strconv.FormatInt(id, 10)).Err()
		if err != nil {
			utils.Error(err)
		}
		if picture.Online {
			err = db.DelPicUploadAccess(picture.AuthorUID, picture.UploadId)
			if err != nil {
				utils.Error(err)
			}
		} else {
			err = db.DelPicUpload(picture.AuthorUID, picture.UploadId)
			if err != nil {
				utils.Error(err)
			}
		}

		// 删除mysql图片
		err = mysql.Del(picture)
		if err != nil {
			utils.Error(err)
			return nil, GenError(err)
		}

		// 删除图片资源
		err = minio_client.Client.RemoveObject(db.PicBucket, picture.Name)
		if err != nil {
			utils.Error(err)
			return nil, GenError(err)
		}
	}

	res = "ok"
	return
}
